﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NewRetail.Application.Components.WeChat.Configurations;
using NewRetail.Application.Components.WeChat.Services;
using NewRetail.Application.Components.WeChat.Services.HttpClients;
using NewRetail.Application.Components.WeChat.TemplateMessage.Model;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;

namespace NewRetail.Application.Components.WeChat.TemplateMessage.Services
{
    /// <summary>
    /// 一个抽象的模板消息服务。
    /// </summary>
    public interface ITemplateMessageService : IApplicationService
    {
        ///// <summary>
        ///// 获取发送模板的Id。
        ///// </summary>
        ///// <param name="templateShortId">模板短Id。</param>
        ///// <returns>发送模板的Id。</returns>
        //string GetTemplateId(string templateShortId);

        /// <summary>
        /// 发送模板消息。
        /// </summary>
        /// <param name="templateMsgSendData"></param>
        /// <returns>消息Id。</returns>
        Task<string> Send(TemplateMsgSendDto templateMsgSendData);
    }

    /// <summary>
    /// 模板消息服务实现。
    /// </summary>
    public class TemplateMessageService : ApplicationService, ITemplateMessageService
    {
        #region Field

        private readonly ILogger _logger;
        private readonly IHttpContextAccessor _accessor;
        private readonly WeChatOptions _wechatOptions;
        private readonly IWeChatApiHttpClientFactory _wechatApiHttpClientFactory;
        private readonly IWeChatAccessToken _weChatAccessToken;
        //private readonly IMapper _mapper;
        #endregion Field

        #region Constructor

        /// <summary>
        /// 初始化一个新的模板消息服务实例。
        /// </summary>
        /// <param name="accountModel">账号模型。</param>
        public TemplateMessageService(IHttpContextAccessor accessor, IWeChatApiHttpClientFactory wechatApiHttpClientFactory,
            IOptions<WeChatOptions> wechatOptions, /*IMapper mapper, */IWeChatAccessToken weChatAccessToken, ILogger<TemplateMessageService> logger)
        {
            _accessor = accessor;
            _wechatOptions = wechatOptions.Value;
            _wechatApiHttpClientFactory = wechatApiHttpClientFactory;
            //_mapper = mapper;
            _weChatAccessToken = weChatAccessToken;
            _logger = logger;
        }

        #endregion Constructor

        #region Implementation of ITemplateMessageService

        #region 发送模板消息
        /// <summary>
        /// 发送模板消息。
        /// </summary>
        /// <param name="templateMsgSendData"></param>
        /// <returns>消息Id。</returns>
        public async Task<string> Send(TemplateMsgSendDto templateMsgSendData)
        {
            var appId = templateMsgSendData.AppId;
            var openId = templateMsgSendData.OpenId;
            var templateId = templateMsgSendData.TemplateId;
            var messageData = templateMsgSendData.MessageItemDate;
            var messageType = templateMsgSendData.MessageType;

            //appId为null则默认获取配置第一个
            if (string.IsNullOrEmpty(appId))
                appId = _wechatOptions.Accounts?.FirstOrDefault().AppId;
            //模板Id为null则默认获取配置第一个，根据类型来获取
            if (string.IsNullOrEmpty(templateId))
                templateId = GetTemplateMsgIdByType(messageType);

            if (string.IsNullOrEmpty(templateId))
                return null;
            ////获取redis里面键对应的值
            //var keyWechatValue = await redis.StringGetAsync(keyWechat);
            ////转成对象
            //var wechatAccessToken = keyWechatValue.IsNullOrEmpty ? null : UtilsHelper.DeserializeObject<WechatAccessTokenEntity>(keyWechatValue.ToString());

            //获取accessToken对象
            var wechatAccessToken = await _weChatAccessToken.GetAccessTokenObject(appId);
            //创建一个http
            var wechatApiclient = _wechatApiHttpClientFactory.Create(appId);
            //请求数据            
            var requestInfo = new CgibinMessageTemplateSendRequest()
            {
                AccessToken = wechatAccessToken?.AccessToken,
                ToUserOpenId = openId,
                TemplateId = templateId,
                Url = "",
                MiniProgram = null,
                Data = messageData
            };
            //请求获取数据
            var responseInfo = await wechatApiclient.ExecuteCgibinMessageTemplateSendAsync(requestInfo, cancellationToken: _accessor.HttpContext.RequestAborted);
            if (!responseInfo.IsSuccessful())
            {
                _logger.LogWarning(
                    "获取信息失败（状态码：{0}，错误代码：{1}，错误描述：{2}）。",
                    responseInfo.RawStatus, responseInfo.ErrorCode, responseInfo.ErrorMessage
                );
                return null;
            }
            return responseInfo.MessageId.ToString();
        }
        #endregion

        #endregion

        #region private method

        #region 根据类型获取模板消息id
        /// <summary>
        /// 根据类型获取模板消息id
        /// </summary>
        /// <param name="messageType"></param>
        /// <returns></returns>
        private string GetTemplateMsgIdByType(int messageType)
        {
            var templateId = "";
            switch (messageType)
            {
                case 0:
                    //购物
                    templateId = _wechatOptions.Accounts?.FirstOrDefault()?.TemplateSendInfo?.ShoppingTemplateId;
                    break;
                case 1:
                    //关注
                    templateId = _wechatOptions.Accounts?.FirstOrDefault()?.TemplateSendInfo?.AttentionTemplateId;
                    break;
                case 2:
                    //积分兑换代金券
                    templateId = _wechatOptions.Accounts?.FirstOrDefault()?.TemplateSendInfo?.IntegralExchangeTemplateId;
                    break;
            }

            return templateId;
        }
        #endregion

        #endregion
    }
}
